package com.multimedia.room.fragment;

import java.io.File;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import android.content.Context;
import android.os.Bundle;
import android.os.CountDownTimer;
import android.os.Handler;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.view.animation.AlphaAnimation;
import android.view.animation.Animation;
import android.view.animation.ScaleAnimation;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

import com.mmclass.libsiren.net.FormFile;
import com.multimedia.room.BaseActivity;
import com.multimedia.room.BaseFragment;
import com.multimedia.room.CommandManager;
import com.multimedia.room.CommonUtil;
import com.multimedia.room.ISwitch;
import com.multimedia.room.MediaMessage;
import com.multimedia.room.OralFileUtils;
import com.multimedia.room.R;
import com.multimedia.room.SwitchManager;
import com.multimedia.room.recorder.Mp3Recorder;
import com.multimedia.room.recorder.VUMeter;
import com.multimedia.room.urlhttp.CallBackUtil;
import com.multimedia.room.urlhttp.UrlHttpUtil;
import com.multimedia.room.view.CircleProgress;

import org.json.JSONException;
import org.json.JSONObject;

public class ExamOralFragment extends BaseFragment implements ISwitch, Mp3Recorder.OnStateChangedListener, BaseActivity.VolumeChangeListener {
    private TextView mExamOverView;
    private String mBasePath;
    private static final String TAG = ExamOralFragment.class.getSimpleName();
    private static final String mAudioPath = "exam/";
    private static final String mAudioName = "exam";
    private static String sAudioFile;
    //	private static int mExamIndex = 1;
    private static String mFloderPath;
    private static String mUploadUrl;
    private static MediaMessage mCurrentMessage;
    public static boolean sIsBroadCast = false;
    private LinearLayout mControllerLayout;
    private LinearLayout mShowLayout;
    private static Context mContext;
    private static final String TYPE_UPLOAD_FILE = "upload_file";
    private static CircleProgress circleProgress;
    private SwitchManager mSwitchManager;
    String mTimerFormat;
    static Handler mHandler = new MsgHandler();
    private static final int MAX_TRY_COUNT = 10;
    private static Object moBjectLock = new Object();
    private static List<String> sUploadFilesList = new ArrayList<String>();
    private static List<String> sWaitForUploadFilesList = new ArrayList<String>();
    private static String sCurrentFileName = null;
    private static String sLastFileName = null;
    private static final long SPLIT_FILE_TIME = 5 * 60 * 1000;
    private static int index = 0;


    static class MsgHandler extends Handler {
        static final int UPLOAD_FILE = 1;
        static final int WHAT_FOR_UPLOAD_PROGRESS = 2;
        static final int SPLIT_RECORD_FILE = 3;

        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);
            synchronized (moBjectLock) {
                final String fileName = (String) msg.obj;
                Log.e(TAG, " handleMessage  msg.what = " + msg.what + " UPLOAD_FILE = " + fileName );
                if (UPLOAD_FILE == msg.what) {
                    try {
                        uploadFile(fileName);
                    } catch (Exception e) {
                        Log.e(TAG, " uploadFile failed retry again!", e);
                        Message msg1 = mHandler.obtainMessage(MsgHandler.UPLOAD_FILE);
                        msg1.obj = fileName;
                        mHandler.sendMessageDelayed(msg1, 1000);
                    }
                } else if (WHAT_FOR_UPLOAD_PROGRESS == msg.what) {
//                    int progress = msg.arg1;
//                    if (circleProgress != null) {
//                        if (circleProgress.getVisibility() != View.VISIBLE) {
//                            circleProgress.setVisibility(View.VISIBLE);
//                        }
//                        circleProgress.setProgress(progress);
//                    }

                } else if (SPLIT_RECORD_FILE == msg.what) {
                    //upload
                    //split
                    Log.i(TAG, "SPLIT_RECORD_FILE");
                    mHandler.post(mSplitRecordRunnable);
                    Message msg1 = mHandler.obtainMessage(MsgHandler.UPLOAD_FILE);
                    msg1.obj = fileName;
                    mHandler.sendMessageDelayed(msg1, 1000);
                }
            }
        }
    }


    private void checkFileUploadStatus() {
        File fileFloder = new File(mFloderPath);
        if (fileFloder.exists() && fileFloder.isDirectory()) {
            File[] files = fileFloder.listFiles();
            if (files != null && files.length > 0) {
                for (int i = 0; i < files.length; i++) {
                    final File file = files[i];
                    Message msg1 = mHandler.obtainMessage(MsgHandler.UPLOAD_FILE);
                    msg1.obj = file.getName();
                    mHandler.sendMessageDelayed(msg1, 1000);
                    Log.i(TAG, "reupload again for " + file.getName());
                }
            }
        }
    }

    ImageView mStateLED;

    TextView mStateMessage1;
    TextView mStateMessage2;
    TextView mTimerView;
    VUMeter mVUMeter;


    @Override
    public void volumeChanger(String value) {
        try {
            if (mVUMeter != null) {
                mVUMeter.setRecorderAngle(Integer.parseInt(value));
//                Log.d(TAG, "volumeChanger: volume   " + value);
            }
        } catch (Exception e) {
            Log.e(TAG, "parse the voice value error ", e);
        }
    }


    @Override
    public void onStart() {
//        em.addHandler(baseEventHandler);
        super.onStart();
    }

    @Override
    public void onStop() {
//        em.removeHandler(baseEventHandler);
        super.onStop();
    }

    // 音频获取源
    public static boolean sIsRecording = false;
//    Mp3Recorder mRecorder;

    public static ExamOralFragment newInstance(MediaMessage message) {
        mCurrentMessage = message;
        CommandManager.openHeadSet();
        ExamOralFragment fragment = new ExamOralFragment();
        return fragment;
    }

    @Override
    public View onCreateView(LayoutInflater inflater, ViewGroup container,
                             Bundle savedInstanceState) {
        View rootView = inflater.inflate(R.layout.exam_oral_layout, null);
        mExamOverView = (TextView) rootView.findViewById(R.id.exam_oral_over);
        ((BaseActivity) getActivity()).setVolumeChangeListener(this);
        circleProgress = (CircleProgress) rootView.findViewById(R.id.circle_progress);
        mControllerLayout = (LinearLayout) rootView.findViewById(R.id.control_layout_1);
        mShowLayout = (LinearLayout) rootView.findViewById(R.id.show_layout);
        mStateMessage1 = (TextView) rootView.findViewById(R.id.stateMessage1);
        mStateMessage2 = (TextView) rootView.findViewById(R.id.stateMessage2);
        mStateMessage1.setText(R.string.oral_exam_alert_1);
        mStateMessage2.setVisibility(View.GONE);
        circleProgress.setPrefixText(getString(R.string.upload_queue));
        circleProgress.setSuffixText(getString(R.string.upload_success));
        mTimerView = (TextView) rootView.findViewById(R.id.timerView);
        mTimerView.setVisibility(View.INVISIBLE);
        mVUMeter = (VUMeter) rootView.findViewById(R.id.uvMeter);
        mContext = this.getActivity();

        mTimerFormat = getResources().getString(R.string.timer_format);

        mSwitchManager = SwitchManager.getInstance();
        mSwitchManager.registerExamSwitch(this);
        mSwitchManager.registerUploadFileSwitch(this);
        mSwitchManager.registerAudioBtoadcaseSwitch(this);
        mBasePath = this.getActivity().getFilesDir().getAbsolutePath();
        Log.d(TAG, mBasePath);
        mUploadUrl = mCurrentMessage.getParams();
        mFloderPath = mBasePath + File.separator + mAudioPath;
        checkFileUploadStatus();
        updateUi();
        return rootView;
    }


    /**
     * Update the big MM:SS timer. If we are in playback, also update the
     * progress bar.
     */
    private void updateTimerView() {

    }

    @Override
    public void switchOn(String params) {
        mExamOverView.setText(R.string.oral_exam_going);
        if (!sIsRecording) {
            sIsRecording = true;
        }

        mControllerLayout.setVisibility(View.GONE);
        mShowLayout.setVisibility(View.VISIBLE);
        mStateMessage1.setText(R.string.oral_exam_alert_2);
//        }
        MyCountTimer myCountTimer = new MyCountTimer(6000, 1000, mShowLayout, mStateMessage2);
        myCountTimer.start();
         mHandler.post(new Runnable() {
            @Override
            public void run() {
              try{
              // CommandManager.closeMic();
               //Thread.sleep(3000);
               CommandManager.openMic();
 		}catch(Exception e){
              }
            }
        });
        Log.d(TAG, "switchOn " + " sIsBroadCast " + sIsBroadCast + "  sIsRecording " + sIsRecording);
    }

    @Override
    public void switchOff(String params) {
        mExamOverView.setText(R.string.oral_exam_ending);
        mHandler.post(new Runnable() {
            @Override
            public void run() {
                stopRecording();
            }
        });
        Log.d(TAG, "switchOff " + " sIsBroadCast " + sIsBroadCast + "  sIsRecording " + sIsRecording);
        // TODO .. post the mp3 file to the server.
    }

    @Override
    public void broadcastOn(String params) {
        if (TYPE_UPLOAD_FILE.equals(params)) {
            Log.i(TAG, " Receive upload command  then upload the file  ");
//            if (uploadTimes > 0 && uploadTimes < MAX_TRY_COUNT) {
//                if (!isUploadFinish) {
//                    Log.i(TAG, " The file is uploading ... return ");
//                    return;
//                }
//
//            } else {
            Log.i(TAG, " Receive upload command  then upload the file  ");
            checkFileUploadStatus();
//            }

        } else {
            Toast.makeText(getActivity(), R.string.audio_broadcast_start, Toast.LENGTH_SHORT).show();

            Log.d(TAG, "broadcastOn " + " sIsBroadCast " + sIsBroadCast + "  sIsRecording " + sIsRecording);
        }
    }

    private static boolean sIsBroadcaseCmd = false;

    @Override
    public void brocadOff(String params) {
        Toast.makeText(getActivity(), R.string.audio_broadcast_end, Toast.LENGTH_SHORT).show();
        sIsBroadcaseCmd = false;
        Log.d(TAG, "brocadOff " + " sIsBroadCast " + sIsBroadCast + "  sIsRecording " + sIsRecording);
    }

    private void startRecording() {

        Log.d(TAG, "startRecording");
//        CommandManager.openMic();
        sIsRecording = true;
        index = 0;
        final String fileName = CommonUtil.getSeatNo() + "_" + mAudioName + "_" + System.currentTimeMillis()
                + ".mp3";
        sLastFileName = fileName;
        File floder = new File(mFloderPath);
        File file = new File(mFloderPath + File.separator + fileName);
        if (floder.exists()) {
            // Nothing to do
        } else {
            floder.mkdirs();
        }
        // 删除录音文件

        try {
            CommandManager.startRecord(file.getAbsolutePath());
            Message msg = mHandler.obtainMessage(MsgHandler.SPLIT_RECORD_FILE);
            msg.obj = fileName;
            mHandler.sendMessageDelayed(msg, SPLIT_FILE_TIME);
        } catch (Throwable t) {
            Log.e("AudioRecord", "Recording Failed");
        }
        uploadTimes = 0;
    }

    private static Runnable mSplitRecordRunnable = new Runnable() {
        @Override
        public void run() {
            splitRecord();
        }
    };

    private static void splitRecord() {

        if (sIsRecording) {

            final String fileName = CommonUtil.getSeatNo() + "_" + mAudioName + "_" + System.currentTimeMillis()
                    + ".mp3";

            sLastFileName = fileName;
            Log.i(TAG, "splitRecord : " + fileName);
            File floder = new File(mFloderPath);
            File file = new File(mFloderPath + File.separator + fileName);
            if (floder.exists()) {
                // Nothing to do
            } else {
                floder.mkdirs();
            }
            // 删除录音文件
            if (file.exists())
                file.delete();
            CommandManager.splitRecord(file.getAbsolutePath());
            Message msg = mHandler.obtainMessage(MsgHandler.SPLIT_RECORD_FILE);
            msg.obj = fileName;
            mHandler.sendMessageDelayed(msg, SPLIT_FILE_TIME);
        }
    }


    private void stopRecording() {
        sIsRecording = false;
        try {
            CommandManager.stopRecord();
            // mRecorder.stopRecording();
        } catch (Exception e1) {
            // TODO Auto-generated catch block
            e1.printStackTrace();
        }
//        CommandManager.closeMic();
        Log.d(TAG, "record over");
        if(!TextUtils.isEmpty(sLastFileName)){
            Message msg = mHandler.obtainMessage(MsgHandler.UPLOAD_FILE);
            msg.obj=sLastFileName;
            mHandler.sendMessageDelayed(msg,1000);
        }
        mHandler.removeMessages(MsgHandler.SPLIT_RECORD_FILE);
        updateUi();
    }




    @Override
    public void onDestroy() {
        super.onDestroy();
        sIsRecording = false;
    }

    @Override
    public void onDestroyView() {
        super.onDestroyView();
        sIsRecording = false;
        try {
            stopRecording();
        } catch (Exception e) {
            e.printStackTrace();
        }
        mSwitchManager.unregisterExamSwitch(this);
        mSwitchManager.unRegisterAudioBtoadcaseSwitch(this);

    }

    static int uploadTimes = 0;
    static boolean isUploadFinish = false;

    @Override
    public void onDetach() {
        super.onDetach();
    }



    private static boolean uploadFile(final String fileName) {
        final File file = new File(mFloderPath, fileName);
        if(!file.exists()){
            Log.d(TAG, "upload file failed due to "+ fileName +" doesn't exits");
            return false;
        }
        CommonUtil.changeMode(mFloderPath);
        CommonUtil.changeMode(file.getAbsolutePath());
        FormFile formfile = new FormFile(fileName, file, "file",
                "application/octet-stream");

        Log.d(TAG,
                "upload start " + mUploadUrl + " === "
                        + fileName
                        + new Date(System.currentTimeMillis())
                        .toString());
        if (file == null) {
//                     Toast.makeText(mContext, "uploadFile failed file is null , return ", Toast.LENGTH_SHORT).show();
            Log.e(TAG, " uploadFile failed file is null , return ");
            return false;
        }


        if (formfile == null) {
//                    Toast.makeText(mContext, "uploadFile failed formfile is null , return", Toast.LENGTH_SHORT).show();

            Log.e(TAG, " uploadFile failed formfile is null , return ");
            return false;
        }

        UrlHttpUtil.uploadFile(mUploadUrl, file, "file", UrlHttpUtil.FILE_TYPE_FILE, new CallBackUtil.CallBackString() {


            @Override
            public void onFailure(int code, String errorMessage) {
                Log.i(TAG, "code " + code + " errorMessage " + errorMessage);
                try {
                    throw new Exception("uploadFile failed");
                } catch (Exception e) {
                    Log.e(TAG, "uploadFile failed ", e);
                }
            }

            @Override
            public void onResponse(String response) {
                Log.i(TAG, "onResponse " + response);
                try {
                    JSONObject rootJson = new JSONObject(response);
                    if (rootJson != null && rootJson.has("Code")) {
                        int code = rootJson.getInt("Code");
                        if (0 == code) {
                            Log.i(TAG, "upload successful " + file.getName());
                            File tmp = new File(mFloderPath + File.separator + file.getName());
                            if(tmp.isFile()){
                                tmp.delete();
                                Log.i(TAG, "upload successful delete local file" + file.getName());
                            }

                        } else {
                            try {
                                throw new Exception("uploadFile failed");
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                        }
                    }
                } catch (JSONException e) {
                    e.printStackTrace();
                }
            }
        });

        CommandManager.sendUpdateCompletionMessage();
        return true;


    }

    private void updateUi() {
        Log.d(TAG, "updateUi");
        updateTimerView();
        mVUMeter.invalidate();
    }

    @Override
    public void onStateChanged(int state) {
        Log.d(TAG, "onStateChanged state " + state);
        mHandler.postDelayed(new Runnable() {
            @Override
            public void run() {
                updateUi();
            }
        }, 1000);
    }

    @Override
    public void onError(int error) {

    }

    class MyCountTimer extends CountDownTimer {
        public static final int TIME_COUNT = 31000;//倒计时总时间为31S，时间防止从29s开始显示（以倒计时30s为例子）
        private TextView mShowTimeView;
        private LinearLayout mShowLayout;
        private String endStrRid;

        /**
         * 参数 millisInFuture         倒计时总时间（如30s,60S，120s等）
         * 参数 countDownInterval    渐变时间（每次倒计1s）
         * 参数 mShowTimeView               点击的按钮(因为Button是TextView子类，为了通用我的参数设置为TextView）
         * 参数 endStrRid   倒计时结束后，按钮对应显示的文字
         */
        public MyCountTimer(long millisInFuture, long countDownInterval, LinearLayout showLayout, TextView tv) {
            super(millisInFuture, countDownInterval);
            this.mShowTimeView = tv;
            this.mShowLayout = showLayout;
            this.mShowTimeView.setVisibility(View.VISIBLE);
        }

        /**
         * 参数上面有注释
         */
        public MyCountTimer(TextView tv, String endStrRid) {
            super(TIME_COUNT, 1000);
            this.mShowTimeView = tv;
            this.endStrRid = endStrRid;
        }

        /**
         * 计时完毕时触发
         */
        @Override
        public void onFinish() {
            mShowTimeView.setText(endStrRid);
            mShowTimeView.setVisibility(View.GONE);
            this.mShowLayout.setVisibility(View.GONE);
            mControllerLayout.setVisibility(View.VISIBLE);
            sIsBroadCast = false;
            sIsBroadcaseCmd = false;
            mHandler.postDelayed(new Runnable() {
                @Override
                public void run() {
                    startRecording();
                    updateUi();
                }
            }, 100);
        }

        /**
         * 计时过程显示
         */
        @Override
        public void onTick(long millisUntilFinished) {
            mShowTimeView.setEnabled(false);
            //每隔一秒修改一次UI
            mShowTimeView.setText(millisUntilFinished / 1000 + "");

            // 设置透明度渐变动画
            final AlphaAnimation alphaAnimation = new AlphaAnimation(0, 1);
            //设置动画持续时间
            alphaAnimation.setDuration(1000);
            mShowTimeView.startAnimation(alphaAnimation);

            // 设置缩放渐变动画
            final ScaleAnimation scaleAnimation = new ScaleAnimation(0.5f, 2f, 0.5f, 2f,
                    Animation.RELATIVE_TO_SELF, 0.5f, Animation.RELATIVE_TO_SELF, 0.5f);
            scaleAnimation.setDuration(1000);
            mShowTimeView.startAnimation(scaleAnimation);
        }
    }
}
